package br.com.async.core.infrastructure;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import br.com.async.core.domain.address.City;
import br.com.async.core.domain.address.State;
import br.com.async.core.domain.person.Person;
import br.com.async.core.domain.person.PersonRepository;

public class PersonRepositoryImpl extends
		AbstractRepositoryImpl<Person, Integer> implements PersonRepository {

	public PersonRepositoryImpl() {
		super(Person.class);
	}

	@Override
	public List<City> findCityByState(Integer code) {
		Criteria criteria = getSession().createCriteria(City.class);
		
		Criterion c1 = Restrictions.eq("state.code", code);
		
		criteria.add(c1);
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		
		return criteria.list();
	}

	@Override
	public List<Person> findByName(String name) {
		Criteria criteria = getSession().createCriteria(entityClass);
		
		Criterion c1 = Restrictions.ilike("name", name, MatchMode.ANYWHERE);
		criteria.add(c1);
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.addOrder(Order.asc("code"));
		return criteria.list();
	}

	@Override
	public List<State> listAllStates() {
		Criteria criteria = getSession().createCriteria(State.class);
		
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		
		return criteria.list();
	}

	@Override
	public List<City> listAllCities() {
		Criteria criteria = getSession().createCriteria(City.class);
		
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.addOrder(Order.asc("code"));
		return criteria.list();
	}

	@Override
	public City findCityById(int code) {
		Criteria criteria = getSession().createCriteria(City.class);
		
		Criterion c1 = Restrictions.eq("code", code);
		criteria.add(c1);
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return (City) criteria.uniqueResult();
	}

}
